home *** CD-ROM | disk | FTP | other *** search
- /* ==========================================================================
- **
- ** ListBrowser.c
- **
- ** ©1991 WILLISoft
- **
- ** ==========================================================================
- */
-
- #include <string.h>
- #include "minmax.h"
- #include "ListBrowser.h"
- #include "ListBrowserClass.h"
- #include "EmbossedGadgetClass.h"
- #include "precognition.h"
- #ifndef __GNUC__
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/diskfont_protos.h>
- #endif
- #ifdef __GNUC__
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/diskfont.h>
- #endif
- #ifdef __SASC
- #include <proto/exec.h>
- #include <proto/intuition.h>
- #include <proto/graphics.h>
- #include <proto/diskfont.h>
- #endif
-
- #include "amigamem.h"
- /* Additions for prototypes -- EDB */
- #include "Intuition_utils.h"
-
- #define CHAR_WIDTH 8 /* Width of Topaz 80 font.*/
- #define CHAR_HEIGHT 9 /* Height of Topaz 80 font.*/
- #define BROWSER_ENTRY_HEIGHT (CHAR_HEIGHT + 1)
- #define BORDER_WIDTH 3
- #define BASELINE 8
-
- #define isSelected(q) ( q & ENTRY_SELECTED )
-
- const StringList *ListBrowser_StringList_of( ListBrowser *self )
- {
- return &self->List;
- }
-
- void ListBrowser_Init( ListBrowser *self,
- PIXELS LeftEdge,
- PIXELS TopEdge,
- PIXELS Width,
- PIXELS Height,
- pcg_3DPens Pens,
- BOOL SelectMany )
- {
-
- EmbossedGadget_Init( &self->eg, LeftEdge, TopEdge, 0, 0,
- GADGHNONE, RELVERIFY, BOOLGADGET, Pens, NULL );
-
- self->eg.isa = ListBrowserClass();
- self->SelectMany = SelectMany;
- self->YOffset = 0;
- SetLocation( (GraphicObject *)self, LeftEdge, TopEdge );
- SetSize( (GraphicObject *)self, Width, Height );
-
- /* Initialize List structure... */
- StringList_Init( &self->List, TRUE );
-
- }
-
- void ListBrowser_CleanUp( ListBrowser *self )
- {
-
-
- StringList_CleanUp( StringList_of( (StringLister *)self ) );
- EmbossedGadget_CleanUp( (EmbossedGadget *)self );
- }
-
- Point ListBrowser_AskSize( ListBrowser *self,
- PIXELS Width,
- PIXELS Height )
- {
- Point size;
- short nCols, nRows;
-
- nCols = ( Width - BORDER_WIDTH * 2 ) / CHAR_WIDTH;
- nRows = ( Height - BORDER_WIDTH * 2 ) / BROWSER_ENTRY_HEIGHT;
-
- nCols = MAX( nCols, 5 );
- nRows = MAX( nRows, 5 );
-
- size.x = nCols*CHAR_WIDTH + BORDER_WIDTH*2;
- size.y = nRows*BROWSER_ENTRY_HEIGHT + BORDER_WIDTH*2;
-
- return size;
- }
-
-
- Point ListBrowser_SetSize( ListBrowser *self,
- PIXELS Width,
- PIXELS Height )
- {
- Point size;
-
- size = AskSize( (GraphicObject *)self, Width, Height );
-
- Forbid(); /* Don't want Intuition looking at these while we modify em. */
- self->eg.Size = size;
- self->eg.g.Width = size.x - BORDER_WIDTH*2;
- self->eg.g.Height = size.y - BORDER_WIDTH*2;
-
- pcg_Init3DBox( self->eg.BoxBorder,
- -BORDER_WIDTH, -BORDER_WIDTH,
- size.x, size.y,
- self->eg.Pens.BrightPen, self->eg.Pens.DarkPen,
- self->eg.BoxBorder->BottomRight.NextBorder );
- Permit();
-
-
- self->nColumns = ( size.x - BORDER_WIDTH * 2 ) / CHAR_WIDTH;
- self->nRows = ( size.y - BORDER_WIDTH * 2 ) / BROWSER_ENTRY_HEIGHT;
-
- /* EDB -- reset Yoffset to zero when resized */
- /* doesn't seem to fix the bug I wanted to fix -- EDB */
- /* ListBrowser_SetYOffset( self, 0 ); */
- return size;
- }
-
- Point ListBrowser_SetLocation( ListBrowser *self,
- PIXELS LeftEdge,
- PIXELS TopEdge )
- {
- Point location;
-
- Forbid();
- self->eg.Location.x = LeftEdge;
- self->eg.Location.y = TopEdge;
- self->eg.g.LeftEdge = LeftEdge + BORDER_WIDTH;
- self->eg.g.TopEdge = TopEdge + BORDER_WIDTH;
- Permit();
-
-
- return location;
- }
-
- USHORT ListBrowser_SetYOffset( ListBrowser *self,
- USHORT YOffset )
- {
- SHORT MaxY;
-
- MaxY = MAX( self->List.nEntries-self->nRows, 0 );
- self->YOffset = MIN( YOffset, MaxY );
-
- return self->YOffset;
- }
-
-
-
- #define DESELECT_ALL(b) ListBrowser_SelectAll( b, FALSE )
-
- void ListBrowser_SelectAll( ListBrowser *self, BOOL Select )
- /* Selects or deselects everything in the list. */
- {
- USHORT i;
-
- for( i = 0; i < self->List.nEntries; i++ )
- {
- if( Select )
- self->List.Qualifiers[i] |= ENTRY_SELECTED;
- else
- self->List.Qualifiers[i] &= (UBYTE) ~ENTRY_SELECTED;
- }
-
- }
-
- void ListBrowser_SelectString( ListBrowser *self,
- USHORT i,
- BOOL Select )
- {
- if( ( ! self->SelectMany ) && ( Select ) )
- DESELECT_ALL( self );
-
- if( Select )
- self->List.Qualifiers[i] |= ENTRY_SELECTED;
- else
- self->List.Qualifiers[i] &= ~ENTRY_SELECTED;
- }
-
- void ListBrowser_DrawEntry( ListBrowser *self,
- RastPort *RPort,
- USHORT index )
- {
- USHORT count, X, Y, Xend, Yend;
- UBYTE qual, succ, pred;
- char **Entries;
- UBYTE *Qualifiers;
- pcg_3DPens pens;
-
- /* Additions for correct font behavior under 2.x/3.x Amiga OS*/
-
- /* TextAttr pcg_Topaz80 =
- { "topaz.font", TOPAZ_EIGHTY, FS_NORMAL, FPF_ROMFONT }; */
-
- struct TextFont *myfont, *oldfont;
-
- Entries = self->List.Entries;
- Qualifiers = self->List.Qualifiers;
-
- X = self->eg.Location.x + BORDER_WIDTH;
- Y = self->eg.Location.y + BORDER_WIDTH
- + (index-self->YOffset) * BROWSER_ENTRY_HEIGHT;
- Xend = X + self->eg.g.Width-1;
- Yend = Y + BROWSER_ENTRY_HEIGHT;
- pens = self->eg.Pens;
-
- SetDrMd( RPort, JAM1 );
- /* Clear the entry. */
- SetAPen( RPort, pens.BackPen );
- RectFill( RPort, X, Y, Xend, Yend );
-
-
- qual = Qualifiers[index];
- if( index )
- pred = Qualifiers[index-1];
- else
- pred = 0;
-
- if( index +1 < self->List.nEntries )
- succ = Qualifiers[index+1];
- else
- succ = 0;
-
-
- if( qual & ENTRY_SPECIAL )
- SetAPen( RPort, pens.FrontPen+1 );
- else
- SetAPen( RPort, pens.FrontPen );
-
- Move( RPort, X+1, Y+BASELINE );
- count = strlen( Entries[index] );
- count = MIN( self->nColumns, count );
-
- /* Under 2.x/3.x AmigaDOS we cannot presume that topaz80 is the default
- * font, so we open it for our use, and close it when done.
- * - EDB
- */
-
- if( myfont = OpenDiskFont( DefaultFont( (GraphicObject *)self ) /* &pcg_Topaz80 */ ) )
- {
- oldfont = RPort->Font;
- SetFont( RPort, myfont );
- Text( RPort, Entries[index], count );
- SetFont( RPort, oldfont );
- CloseFont( myfont );
- }
-
-
- if( isSelected( qual ) )
- {
- SetDrMd( RPort, COMPLEMENT );
-
- /* Draw 3D lines. */
- RectFill( RPort, X, Y, Xend, Yend );
- SetDrMd( RPort, JAM1 );
- SetAPen( RPort, pens.DarkPen );
- Move( RPort, X, Yend );
- Draw( RPort, X, Y );
-
- SetAPen( RPort, pens.BrightPen ); /* Right side bar. */
- Move( RPort, Xend, Y );
- Draw( RPort, Xend, Yend );
- }
-
- /* Draw top bar. */
- if( ( ( !isSelected( pred ) ) && isSelected( qual ) ) )
- /* previous is not selected, entry is */
- {
- SetAPen( RPort, pens.DarkPen );
- Move( RPort, X, Y );
- Draw( RPort, Xend, Y );
- }
- else if( isSelected( pred ) && ( !isSelected( qual ) ) )
- /* previous is selected, entry is not */
- {
- SetAPen( RPort, pens.BrightPen );
- Move( RPort, X, Y );
- Draw( RPort, Xend, Y );
- }
-
- /* Draw bottom bar */
- if( ( !isSelected( succ ) ) && isSelected( qual ) )
- /* successor is not selected, entry is */
- {
- SetAPen( RPort, pens.BrightPen );
- Move( RPort, X, Yend );
- Draw( RPort, Xend, Yend );
- }
- else if( isSelected( succ ) && ( !isSelected( qual ) ) )
- /* successor is selected, entry is not */
- {
- SetAPen( RPort, pens.DarkPen );
- Move( RPort, X, Yend );
- Draw( RPort, Xend, Yend );
- }
- }
-
-
- void ListBrowser_Render( ListBrowser *self,
- RastPort *RPort )
- {
- USHORT X, Y, Xend, Yend;
- USHORT i, j;
-
- X = self->eg.g.LeftEdge;/* + BORDER_WIDTH;*/
- Y = self->eg.g.TopEdge; /* + BORDER_WIDTH;*/
- Xend = X + self->eg.g.Width-1;
- Yend = Y + self->eg.g.Height-1;
-
-
- DrawBorder( RPort, (struct Border *)self->eg.BoxBorder, self->eg.g.LeftEdge, self->eg.g.TopEdge );
-
- /* Clear the display area. */
- SetDrMd( RPort, JAM1 );
- SetAPen( RPort, self->eg.Pens.BackPen );
- RectFill( RPort, X, Y, Xend, Yend );
-
-
- /* Display the list */
- for( j = 0, i = self->YOffset; j < self->nRows; j++, i++)
- {
- if( i >= self->List.nEntries ) break;
- ListBrowser_DrawEntry( self, RPort, i );
- }
- }
-
-
- void ListBrowser_ChangeHighlight( ListBrowser *self,
- USHORT new_highlighted_entry, /* index */
- RastPort *RPort )
- {
- USHORT i, j;
- UBYTE *Qualifiers;
-
-
- /* Display the list */
- Qualifiers = self->List.Qualifiers;
-
- /* Deselect the old one. */
- i = self->YOffset;
- for( j = 0; j < self->nRows; j++, i++ )
- {
- if( i >= self->List.nEntries ) break;
-
- if( isSelected( Qualifiers[i] ) )
- {
- /* If this is the old highlight */
- Qualifiers[i] &= ~ENTRY_SELECTED;
- ListBrowser_DrawEntry( self, RPort, i );
- }
- }
-
- Qualifiers[new_highlighted_entry] |= ENTRY_SELECTED;
-
- if( ( new_highlighted_entry - self->YOffset >= 0 ) &&
- ( new_highlighted_entry - self->YOffset < self->nRows ) )
- ListBrowser_DrawEntry( self, RPort, new_highlighted_entry );
-
- }
-
- /* Changed from ListBrowser * */
- void ListBrowser_Refresh( Interactor *self )
- {
- struct pcgWindow *window;
-
- window = InteractorWindow( (Interactor *)self );
- Render( (GraphicObject *)self, window->Window->RPort );
- }
-
-
- /* Changed from void -- EDB */
- BOOL ListBrowser_AddString( ListBrowser *self,
- char *entry,
- UBYTE qualifier )
- {
- if( ( ! self->SelectMany ) && isSelected( qualifier ) )
- DESELECT_ALL( self );
- /* This new entry is selected, so all others must be deselected. */
- /* added return -- EDB */
- return( StringList_AddString( &self->List, entry, qualifier ) );
- }
-
-
- BOOL ListBrowser_DeleteString( ListBrowser *self, USHORT i )
- {
- BOOL result;
- StringList *sl;
-
- /*DUMPWAIT("ListBrowser_DeleteString\n");*/
-
- sl = StringList_of( (StringLister *)self );
-
- result = StringList_DeleteString( sl, i );
-
- ListBrowser_SetYOffset( self, self->YOffset );
-
- /*DUMPWAIT("end ListBrowser_DeleteString\n");*/
-
- return result;
-
- }
-
- BOOL ListBrowser_DeleteAllStrings( ListBrowser *self )
- {
- BOOL result;
-
- result = StringList_DeleteAllStrings( &self->List );
- ListBrowser_SetYOffset( self, self->YOffset );
-
- return result;
- }
-
-
-
- #define CLAIM_EVENT(b,e) ( &b->eg.g == (Gadget *)e->IAddress )
-
- USHORT ListBrowser_Respond( ListBrowser *self,
- IntuiMessage *Event )
- {
- Point Mouse;
- USHORT entry_no;
- USHORT response = 0;
- UBYTE qual;
-
- switch( Event->Class )
- {
- case REFRESHWINDOW:
- ListBrowser_Render( self, Event->IDCMPWindow->RPort );
- response = RESPONDED;
- break;
-
- case GADGETUP:
- if( CLAIM_EVENT( self, Event ) )
- {
- /* Translate into Gadget-Relative Coordinates. */
- GadgetRelativeCoords( &self->eg.g, Event, &Mouse );
- entry_no = ( Mouse.y - BORDER_WIDTH ) / BROWSER_ENTRY_HEIGHT
- + self->YOffset;
- entry_no = MAX( entry_no, 0 );
-
- qual = self->List.Qualifiers[entry_no];
-
- if( entry_no < self->List.nEntries )
- {
- if( self->SelectMany )
- {
- SelectString( (StringLister *)self, entry_no, !isSelected( qual ) );
- ListBrowser_DrawEntry( self,
- Event->IDCMPWindow->RPort, entry_no );
- }
- else
- {
- if( !isSelected( qual ) ) /* Only select if not already. */
- { /* (Avoids ugly screen update.) */
- ListBrowser_ChangeHighlight( self, entry_no,
- Event->IDCMPWindow->RPort );
- }
- }
- }
- response = RESPONDED | CHANGED_STATE | CONSUMED_EVENT;
- }
- break;
-
- }
- return response;
- }
-
-
-
- BOOL ListBrowser_elaborated = FALSE;
-
- struct StringListerClass ListBrowser_Class;
-
- void ListBrowserClass_Init( struct StringListerClass *class )
- {
-
- StringListerClass_Init( class );
- EmbossedGadgetClass_Init( (struct InteractorClass *)class );
- class->isa = StringListerClass();
- class->ClassName = "ListBrowser";
- class->CleanUp = (void(*)(PObject *))ListBrowser_CleanUp;
- class->AskSize = (Point(*)(GraphicObject *, PIXELS, PIXELS))ListBrowser_AskSize;
- class->SetSize = (Point(*)(GraphicObject *, PIXELS, PIXELS))ListBrowser_SetSize;
- class->SizeFlags = GraphicObject_SizeFlagsAll;
- class->SetLocation = (Point(*)(GraphicObject *, PIXELS, PIXELS))ListBrowser_SetLocation;
- class->Respond = (USHORT(*)(Interactor *, IntuiMessage *))ListBrowser_Respond;
- class->Render = (void(*)(GraphicObject *, RastPort *))ListBrowser_Render;
- class->Refresh = (void(*)(Interactor *))ListBrowser_Refresh;
-
- class->AddString = (BOOL(*)(StringLister *, char *, UBYTE))ListBrowser_AddString;
- class->DeleteString = (BOOL(*)(StringLister *, USHORT))ListBrowser_DeleteString;
- class->DeleteAllStrings = (BOOL(*)(StringLister *))ListBrowser_DeleteAllStrings;
- class->StringList_of = (StringList*(*)(StringLister *))ListBrowser_StringList_of;
- class->SelectString = (void(*)(StringLister *, USHORT, BOOL))ListBrowser_SelectString;
- }
-
-
- struct StringListerClass *ListBrowserClass( void )
- {
- if( ! ListBrowser_elaborated )
- {
- ListBrowserClass_Init( &ListBrowser_Class );
- ListBrowser_elaborated = TRUE;
- }
-
- return &ListBrowser_Class;
- }
-